-------------------------------------------------------------------------------
-- Archivo: 			         op_unit.vhdl
-- Fecha de creación:            25/01/2011
-- Última fecha de modificación: 28/01/2011
-- Diseñador: 			         Cesar A. Fuguet T.
-- Diseño: 			             op_unit
-- Propósito: 			         Unidad generadora de operaciones a realizar en
--                               la UAL. Se generan en base al contador y la
--                               instrucción que se esta ejecutando actualmente
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

entity op_unit is
  
    port (
        OPCODE_i  : in  std_logic_vector(3 downto 0);
        FFT_STG_i : in  std_logic_vector(2 downto 0);
        COUNTER_i : in  std_logic_vector(1 downto 0);
        ALU_OP_o  : out std_logic_vector(3 downto 0));

end op_unit;

architecture behavioral of op_unit is
    constant FFT_OPCODE : std_logic_vector(3 downto 0) := X"F";
    constant ADD_OPCODE : std_logic_vector(3 downto 0) := X"0";
    constant SUB_OPCODE : std_logic_vector(3 downto 0) := X"1";

    constant FFT_STAGE0 : std_logic_vector(2 downto 0) := "000";
    constant FFT_STAGE1 : std_logic_vector(2 downto 0) := "001";
    constant FFT_STAGE2 : std_logic_vector(2 downto 0) := "010";
    constant FFT_STAGE3 : std_logic_vector(2 downto 0) := "011";
    constant FFT_IDLE : std_logic_vector(2 downto 0) := "111";

    signal is_fft : std_logic;

    signal fft_op : std_logic_vector(3 downto 0);
    signal fft_op_map : std_logic_vector(3 downto 0);
  
begin  -- behavioral

    is_fft <= '1' when OPCODE_i = FFT_OPCODE else
            '0';

    fft_op_map <= FFT_STG_i(1 downto 0) & COUNTER_i;

    with fft_op_map select
    fft_op <=
        ADD_OPCODE when X"0",
        SUB_OPCODE when X"1",
        ADD_OPCODE when X"2",
        SUB_OPCODE when X"3",
        ADD_OPCODE when X"4",
        SUB_OPCODE when X"5",
        ADD_OPCODE when X"6",
        SUB_OPCODE when X"7",
        ADD_OPCODE when X"8",
        ADD_OPCODE when X"9",
        ADD_OPCODE when X"A",
        SUB_OPCODE when X"B",
        SUB_OPCODE when X"C",
        SUB_OPCODE when X"D",
        SUB_OPCODE when X"E",
        ADD_OPCODE when others;

    with is_fft select
    ALU_OP_o <=
        fft_op   when '1',
        OPCODE_i when others;
  
end behavioral;

-- vim: tabstop=4 : expandtab : shiftwidth=4
